use std::collections::HashMap;
use std::fs::File;
use std::io::{self, Read};
use std::iter;
use std::path::Path;

use anyhow::{anyhow, Context, Result};
use calamine::{open_workbook, Reader, Xlsx};
use chrono::{Datelike, NaiveDateTime};
use clap::{ArgAction, Parser};
use log::{error, info, warn};
use polars::prelude::*;
use regex::Regex;
use rust_xlsxwriter::{Color, Format, Workbook, Worksheet};
use serde::{Deserialize, Serialize};
use serde_json::{self, Value};
use simple_logger::SimpleLogger;

/// 默认配置
const DEFAULT_CONFIG: &str = r#"{
  "file_paths": {
    "excel_files": [],
    "paypal_csv_files": [],
    "air_csv_files": []
  },
  "output": {
    "export_file_name": "",
    "auto_name": true
  },
  "keywords":["订单编号","支付订单号","交易号","交易编号", "货币单位", "订单总价"],
  "known_channels": [
    "长沙",
    "华宁",
    "尼彩"
  ],
  "main_data": {
    "header": [
      "支付订单号",
      "货币单位",
      "订单总价",
      "商品总价",
      "优惠金额",
      "物流费用",
      "支付状态",
      "支付方式1",
      "支付渠道1",
      "支付金额1",
      "最后一次互动来源",
      "订单确认时间"
    ],
    "numeric_fields": [
      "订单总价",
      "商品总价",
      "优惠金额",
      "物流费用"
    ],
    "payment_status_filter": [
      "部分退款",
      "已支付"
    ],
    "paypal_header": [
      "交易号",
      "币种",
      "总额",
      "费用",
      "净额",
      "类型",
      "状态",
      "来源"
    ],
    "paypal_checkout_types": [
      "快速结账付款",
      "直接信用卡付款",
      "预先批准付款账单用户付款"
    ],
    "air_header": [
      "交易编号",
      "交易币种",
      "交易金额",
      "授权状态返回描述",
      "交易状态",
      "来源"
    ],
    "air_checkout_types": [
      "FULLY REFUNDED",
      "PARTIALLY REFUNDED",
      "SUCCEEDED",
      "DISPUTED"
    ]
  }
}"#;

/// 配置结构
#[derive(Debug, Deserialize, Serialize, Clone)]
struct Config {
    file_paths: FilePaths,
    output: OutputConfig,
    keywords: Vec<String>,
    known_channels: Vec<String>,
    main_data: MainData,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
struct FilePaths {
    excel_files: Vec<String>,
    paypal_csv_files: Vec<String>,
    air_csv_files: Vec<String>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
struct OutputConfig {
    export_file_name: String,
    auto_name: bool,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
struct MainData {
    header: Vec<String>,
    numeric_fields: Vec<String>,
    payment_status_filter: Vec<String>,
    paypal_header: Vec<String>,
    paypal_checkout_types: Vec<String>,
    air_header: Vec<String>,
    air_checkout_types: Vec<String>,
}

/// 命令行参数
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// Excel文件路径，可以指定多个文件
    #[arg(long, required = false, num_args = 1..)]
    excel: Option<Vec<String>>,

    /// PayPal CSV文件路径，可以指定多个文件
    #[arg(long, required = false, num_args = 1..)]
    paypal: Option<Vec<String>>,

    /// 云汇 CSV文件路径，可以指定多个文件
    #[arg(long, required = false, num_args = 1..)]
    air: Option<Vec<String>>,

    /// 输出Excel文件名
    #[arg(long, required = false)]
    output: Option<String>,

    /// 交互模式
    #[arg(short, long, action = ArgAction::SetTrue)]
    interactive: bool,
}

/// 加载配置文件
fn load_config(config_path: &str) -> Result<Config> {
    if Path::new(config_path).exists() {
        let mut file = File::open(config_path)
            .with_context(|| format!("无法打开配置文件: {}", config_path))?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)
            .with_context(|| format!("无法读取配置文件: {}", config_path))?;

        let config: Config = serde_json::from_str(&contents)
            .with_context(|| format!("无法解析配置文件: {}", config_path))?;

        info!("已加载配置文件: {}", config_path);
        Ok(config)
    } else {
        // 创建默认配置文件
        let config: Config = serde_json::from_str(DEFAULT_CONFIG).context("无法解析默认配置")?;

        std::fs::write(
            config_path,
            serde_json::to_string_pretty(&config).context("无法序列化默认配置")?,
        )
        .with_context(|| format!("无法写入默认配置文件: {}", config_path))?;

        info!("已创建默认配置文件: {}", config_path);
        Ok(config)
    }
}

/// 创建唯一的文件名
fn create_filename(filename: &str) -> String {
    let path = Path::new(filename);
    let stem = path.file_stem().unwrap_or_default().to_string_lossy();
    let extension = path.extension().unwrap_or_default().to_string_lossy();

    let mut count = 1;
    let mut new_filename = filename.to_string();

    while Path::new(&new_filename).exists() {
        new_filename = format!("{stem}({count}).{extension}");
        count += 1;
    }

    new_filename
}

/// 确定渠道
fn determine_channel(file_path: &str, known_channels: &[String]) -> String {
    let file_name = Path::new(file_path)
        .file_name()
        .unwrap_or_default()
        .to_string_lossy();

    // 先尝试匹配已知渠道
    for channel in known_channels {
        if file_name.contains(channel) {
            return channel.clone();
        }
    }

    // 安全地获取前两个字符（使用字符迭代器）
    let prefix: String = file_name.chars().take(2).collect();

    // 如果确实取到了两个字符才返回
    if prefix.chars().count() == 2 {
        prefix
    } else {
        String::new()
    }
}
fn last_day_of_month(year: i32, month: u32) -> u32 {
    match month {
        1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
        4 | 6 | 9 | 11 => 30,
        2 => {
            if (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) {
                29
            } else {
                28
            }
        }
        _ => 0, // 无效月份返回 None
    }
}

/// 判断日期是否为月末最后一天
fn is_last_day_of_month(date_str: &str) -> bool {
    if date_str.is_empty() {
        return false;
    }

    // 尝试标准格式解析
    if let Ok(date) = NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S") {
        let year = date.year();
        let month = date.month();
        let day = date.day();

        // 获取该月的最后一天
        let last_day = last_day_of_month(year, month);

        return day == last_day;
    }

    // 尝试其他常见格式
    let patterns = [
        Regex::new(r"^(\d{4})[-./年](\d{1,2})[-./月](\d{1,2})").unwrap(),
        Regex::new(r"^(\d{1,2})[-./月](\d{1,2})[-./日],(\d{4})").unwrap(),
    ];

    for pattern in patterns.iter() {
        if let Some(captures) = pattern.captures(date_str) {
            if captures.len() >= 4 {
                let year: i32 = captures[1].parse().unwrap_or(0);
                let month: u32 = captures[2].parse().unwrap_or(0);
                let day: u32 = captures[3].parse().unwrap_or(0);

                if year > 0 && month > 0 && month <= 12 && day > 0 {
                    // 获取该月的最后一天
                    let last_day = last_day_of_month(year, month);

                    return day == last_day;
                }
            }
        }
    }

    false
}

/// 读取Excel文件数据
fn get_xlsx_data(
    file_path: &str,
    keywords: &[String],
    known_channels: &[String],
) -> Result<Vec<HashMap<String, Value>>> {
    info!("读取文件: {}", file_path);

    // 使用calamine打开Excel文件
    let mut workbook: Xlsx<_> =
        open_workbook(file_path).with_context(|| format!("无法打开Excel文件: {}", file_path))?;

    // 获取第一个工作表
    // let sheet_name = workbook
    //     .sheet_names()
    //     .get(0)
    //     .ok_or_else(|| anyhow!("Excel文件没有工作表"))?;
    let sheet_names = workbook.sheet_names(); // 延长临时值的生命周期
    let sheet_name = sheet_names
        .first()
        .ok_or_else(|| anyhow!("Excel文件没有工作表"))?;
    let range = workbook
        .worksheet_range(sheet_name)
        .with_context(|| format!("无法读取工作表: {}", sheet_name))?;

    // 自动检测表头行
    let mut header_row = 0;
    let max_rows = std::cmp::min(9, range.height());
    for i in 0..max_rows {
        let has_keyword = (0..range.width()).any(|j| {
            if let Some(cell) = range.get_value((i.try_into().unwrap(), j.try_into().unwrap())) {
                let cell_str = cell.to_string();
                keywords.iter().any(|k| cell_str.contains(k))
            } else {
                false
            }
        });

        if has_keyword {
            header_row = i;
            break;
        }
    }

    // 提取表头
    let mut headers = Vec::new();
    for j in 0..range.width() {
        if let Some(cell) = range.get_value((header_row.try_into().unwrap(), j.try_into().unwrap()))
        {
            headers.push(cell.to_string());
        } else {
            headers.push(format!("Column_{}", j));
        }
    }

    // 转换为HashMap数组
    let mut result = Vec::new();
    let channel = determine_channel(file_path, known_channels);

    // 从表头行的下一行开始处理数据
    for i in (header_row + 1)..range.height() {
        let mut temp_data = HashMap::new();

        // 首先收集所有数据到临时HashMap
        for (j, header) in headers.iter().enumerate() {
            if j < range.width() {
                if let Some(cell) = range.get_value((i.try_into().unwrap(), j.try_into().unwrap()))
                {
                    let value = match cell {
                        calamine::DataType::String(s) => Value::String(s.to_string()),
                        calamine::DataType::Float(f) => {
                            if let Some(num) = serde_json::Number::from_f64(*f) {
                                Value::Number(num)
                            } else {
                                Value::String(f.to_string())
                            }
                        }
                        calamine::DataType::Int(i) => Value::Number(serde_json::Number::from(*i)),
                        calamine::DataType::Bool(b) => Value::Bool(*b),
                        _ => Value::String(cell.to_string()),
                    };
                    temp_data.insert(header.clone(), value);
                }
            }
        }

        // 添加来源字段
        temp_data.insert("来源".to_string(), Value::String(channel.clone()));

        // 重新组织数据，确保支付订单号字段在最前面（如Python版本）
        let mut row_data = HashMap::new();
        
        // 优先处理并添加支付订单号字段
        for (key, value) in &temp_data {
            if key.contains("支付订单号") {
                row_data.insert("支付订单号".to_string(), value.clone());
                break;
            }
        }
        
        // 添加其他字段并保持原有顺序
        for (key, value) in temp_data {
            if !row_data.contains_key(&key) {
                row_data.insert(key, value);
            }
        }

        result.push(row_data);
    }

    info!("读取了 {} 行数据", result.len());
    Ok(result)
}

/// 读取CSV文件数据
fn get_csv_data(file_path: &str, known_channels: &[String]) -> Result<Vec<HashMap<String, Value>>> {
    let channel = determine_channel(file_path, known_channels);

    // 读取CSV文件数据
    let mut file =
        File::open(file_path).with_context(|| format!("无法打开CSV文件: {}", file_path))?;
    let mut content = String::new();
    file.read_to_string(&mut content)
        .with_context(|| format!("无法读取CSV文件内容: {}", file_path))?;

    // 将内容分割成行
    let lines: Vec<&str> = content.lines().collect();

    // 查找真正的CSV头部行
    let mut header_row = 0;
    let csv_header = [
        "订单编号",
        "支付订单号",
        "交易号",
        "交易编号",
        "货币单位",
        "订单总价",
    ];

    // 只检查前9行
    for (i, line) in lines.iter().take(9).enumerate() {
        // 检查是否是有效的CSV头部行
        if csv_header.iter().any(|header| line.contains(header)) || line.matches(',').count() > 10 {
            header_row = i;
            break;
        }
    }

    // 如果找到了头部行，从该行开始解析CSV
    let content_from_header = lines[header_row..].join("\n");

    // 使用内存中的内容创建CSV读取器
    let df = CsvReader::new(std::io::Cursor::new(content_from_header.as_bytes()))
        .has_header(true)
        .with_ignore_errors(true) // 忽略解析错误
        .finish()
        .with_context(|| format!("无法解析CSV文件: {}", file_path))?;

    // 转换为HashMap数组
    let mut result = Vec::new();

    for row_idx in 0..df.height() {
        let mut row_data = HashMap::new();

        // 添加来源字段
        row_data.insert("来源".to_string(), Value::String(channel.clone()));

        // 处理其他字段
        for col_idx in 0..df.width() {
            if let Some(column) = df.select_at_idx(col_idx) {
                let column_name = column.name().to_string();
                if let Ok(value) = column.get(row_idx) {
                    // 手动将AnyValue转换为serde_json::Value
                    let json_value = match value {
                        AnyValue::Null => Value::Null,
                        AnyValue::Boolean(b) => Value::Bool(b),
                        AnyValue::Int32(i) => Value::Number(serde_json::Number::from(i as i64)),
                        AnyValue::Int64(i) => Value::Number(serde_json::Number::from(i)),
                        AnyValue::UInt32(i) => Value::Number(serde_json::Number::from(i as u64)),
                        AnyValue::UInt64(i) => Value::Number(serde_json::Number::from(i)),
                        AnyValue::Float32(f) => {
                            if let Some(num) = serde_json::Number::from_f64(f as f64) {
                                Value::Number(num)
                            } else {
                                Value::String(f.to_string())
                            }
                        }
                        AnyValue::Float64(f) => {
                            if let Some(num) = serde_json::Number::from_f64(f) {
                                Value::Number(num)
                            } else {
                                Value::String(f.to_string())
                            }
                        }
                        AnyValue::Utf8(s) => Value::String(s.to_string()),
                        AnyValue::List(l) => {
                            Value::String(format!("[List with {} items]", l.len()))
                        }
                        _ => Value::String(value.to_string()),
                    };
                    row_data.insert(column_name.clone(), json_value);
                }
            }
        }

        result.push(row_data);
    }

    info!("CSV读取完成，结果：{} 行", result.len());
    Ok(result)
}

/// 处理数据的通用函数
fn process_data<F>(
    data: &[HashMap<String, Value>],
    header: &[String],
    numeric_fields: &[String],
    condition: F,
) -> Vec<HashMap<String, Value>>
where
    F: Fn(&HashMap<String, Value>) -> bool,
{
    let mut result = Vec::new();

    for item in data {
        let payment_status = item.get("支付状态").and_then(|v| v.as_str()).unwrap_or("");

        if ["部分退款", "已支付"].contains(&payment_status) && condition(item) {
            let mut obj = HashMap::new();

            for key in header {
                let value = item.get(key).cloned().unwrap_or(Value::Null);

                // 将数值字段转换为浮点数
                if numeric_fields.contains(key) {
                    let num_value = match value {
                        Value::String(s) => s.parse::<f64>().unwrap_or(0.0),
                        Value::Number(n) => n.as_f64().unwrap_or(0.0),
                        _ => 0.0,
                    };
                    obj.insert(
                        key.clone(),
                        Value::Number(
                            serde_json::Number::from_f64(num_value)
                                .unwrap_or(serde_json::Number::from(0)),
                        ),
                    );
                } else {
                    obj.insert(key.clone(), value);
                }
            }

            result.push(obj);
        }
    }

    result
}

/// 根据输入文件名生成导出文件名
fn get_export_filename(files: &[String], name: Option<String>) -> String {
    if let Some(name) = name {
        return name;
    }

    if files.is_empty() {
        return "数据汇总.xlsx".to_string();
    }

    // 从第一个文件名提取前缀和日期范围
    let file_name = Path::new(&files[0])
        .file_name()
        .unwrap_or_default()
        .to_string_lossy();
    let pattern = Regex::new(r"^([A-Za-z]{2,}).*?(\d+\.\d+-\d+\.\d+)").unwrap();

    if let Some(captures) = pattern.captures(&file_name) {
        if captures.len() >= 3 {
            let prefix = &captures[1];
            let date_range = &captures[2];
            return format!("{}{}{}", prefix, date_range, "汇总.xlsx");
        }
    }

    "数据汇总.xlsx".to_string()
}

/// 计算不同货币的总和
fn currency_sum(
    data: &[HashMap<String, Value>],
    cur_field: &str,
    sum_field: &str,
) -> HashMap<String, f64> {
    let mut currency_obj = HashMap::new();

    for item in data {
        // 跳过计数为2的项
        if let Some(Value::Number(count)) = item.get("计数") {
            if count.as_i64() != Some(1) {
                continue;
            }
        }

        if let Some(Value::String(currency)) = item.get(cur_field) {
            let amount = match item.get(sum_field) {
                Some(Value::Number(n)) => n.as_f64().unwrap_or(0.0),
                Some(Value::String(s)) => s.parse::<f64>().unwrap_or(0.0),
                _ => 0.0,
            };

            *currency_obj.entry(currency.clone()).or_insert(0.0) += amount;
        }
    }

    currency_obj
}

/// 获取数据（支持Excel和CSV）
fn get_data(
    file_path: &str,
    keywords: &[String],
    known_channels: &[String],
) -> Result<Vec<HashMap<String, Value>>> {
    let extension = Path::new(file_path)
        .extension()
        .and_then(|ext| ext.to_str())
        .unwrap_or("")
        .to_lowercase();

    match extension.as_str() {
        "csv" | "CSV" => get_csv_data(file_path, known_channels),
        "xlsx" | "xls" => get_xlsx_data(file_path, keywords, known_channels),
        _ => Err(anyhow!("不支持的文件格式: {}", extension)),
    }
}

/// 主函数，处理Excel和CSV数据并导出结果
fn process_files(
    excel_files: &[String],
    paypal_csv_files: &[String],
    air_csv_files: &[String],
    export_file_name: Option<String>,
    config: &Config,
) -> Result<String> {
    // 读取Excel文件
    let mut new_data = Vec::new();
    for file_path in excel_files {
        match get_data(file_path, &config.keywords, &config.known_channels) {
            Ok(data) => new_data.extend(data),
            Err(e) => warn!("读取文件 {} 失败: {}", file_path, e),
        }
    }

    let main_data = &config.main_data;

    // 筛选条件1：部分退款或已支付，且支付渠道不是空中云汇
    let pay_data = process_data(
        &new_data,
        &main_data.header,
        &main_data.numeric_fields,
        |item| {
            item.get("支付渠道1")
                .and_then(|v| v.as_str())
                .map(|s| s != "空中云汇")
                .unwrap_or(false)
        },
    );

    // 筛选条件2：对应云汇
    let air_data = process_data(
        &new_data,
        &main_data.header,
        &main_data.numeric_fields,
        |item| {
            item.get("支付渠道1")
                .and_then(|v| v.as_str())
                .map(|s| s == "空中云汇")
                .unwrap_or(false)
        },
    );

    // 读取PayPal CSV数据
    let mut csv_data = Vec::new();
    for csv_file in paypal_csv_files {
        match get_data(csv_file, &config.keywords, &config.known_channels) {
            Ok(data) => csv_data.extend(data),
            Err(e) => warn!("读取文件 {} 失败: {}", csv_file, e),
        }
    }

    // 读取云汇CSV数据
    let mut csv_data2 = Vec::new();
    for csv_file in air_csv_files {
        match get_data(csv_file, &config.keywords, &config.known_channels) {
            Ok(data) => csv_data2.extend(data),
            Err(e) => warn!("读取文件 {} 失败: {}", csv_file, e),
        }
    }

    // 处理PayPal数据
    let mut pay_data2 = Vec::new();
    for item in &pay_data {
        let mut is_repeat = false;
        let payment_order_id = item
            .get("支付订单号")
            .and_then(|v| v.as_str())
            .unwrap_or("");

        for csv_item in &csv_data {
            let transaction_id = csv_item
                .get("交易号")
                .and_then(|v| v.as_str())
                .unwrap_or("");
            let is_same = transaction_id == payment_order_id;

            if is_same {
                let status = csv_item.get("状态").and_then(|v| v.as_str()).unwrap_or("");
                let transaction_type = csv_item.get("类型").and_then(|v| v.as_str()).unwrap_or("");

                if status == "已完成"
                    && main_data
                        .paypal_checkout_types
                        .contains(&transaction_type.to_string())
                {
                    // 检查订单确认时间是否为月末
                    let order_time = item
                        .get("订单确认时间")
                        .and_then(|v| v.as_str())
                        .unwrap_or("");
                    let is_month_end = is_last_day_of_month(order_time);

                    let mut new_obj = HashMap::new();
                    for key in &main_data.paypal_header {
                        let value = csv_item.get(key).cloned().unwrap_or(Value::Null);

                        // 将数值字段转换为浮点数
                        if ["总额", "费用", "净额"].contains(&key.as_str()) {
                            let num_value = match value {
                                Value::String(s) => s.parse::<f64>().unwrap_or(0.0),
                                Value::Number(n) => n.as_f64().unwrap_or(0.0),
                                _ => 0.0,
                            };
                            new_obj.insert(
                                key.clone(),
                                Value::Number(
                                    serde_json::Number::from_f64(num_value)
                                        .unwrap_or(serde_json::Number::from(0)),
                                ),
                            );
                        } else {
                            new_obj.insert(key.clone(), value);
                        }
                    }

                    // 设置计数值，初始为1
                    let count = if is_repeat { 2 } else { 1 };
                    new_obj.insert(
                        "计数".to_string(),
                        Value::Number(serde_json::Number::from(count)),
                    );

                    // 如果是月末，添加标记
                    if is_month_end {
                        new_obj.insert("_isMonthEnd".to_string(), Value::Bool(true));
                        // 同时为原始数据项添加标记，与Python版本保持一致
                        let mut item_mut = item.clone();
                        item_mut.insert("_isMonthEnd".to_string(), Value::Bool(true));
                    }

                    is_repeat = true;
                    pay_data2.push(new_obj);
                }
            }
        }
    }
    info!("PayPal CSV 数据长度: {}", pay_data2.len());


    // 处理云汇数据
    let mut air_data2 = Vec::new();
    for item in &air_data {
        let mut is_repeat = false;
        let payment_order_id = item
            .get("支付订单号")
            .and_then(|v| v.as_str())
            .unwrap_or("");

        for csv_item in &csv_data2 {
            let transaction_id = csv_item
                .get("交易编号")
                .and_then(|v| v.as_str())
                .unwrap_or("");
            let is_same = transaction_id == payment_order_id;

            if is_same {
                let transaction_status = csv_item
                    .get("交易状态")
                    .and_then(|v| v.as_str())
                    .unwrap_or("");

                if main_data
                    .air_checkout_types
                    .contains(&transaction_status.to_string())
                {
                    // 检查订单确认时间是否为月末
                    let order_time = item
                        .get("订单确认时间")
                        .and_then(|v| v.as_str())
                        .unwrap_or("");
                    let is_month_end = is_last_day_of_month(order_time);

                    let mut new_obj = HashMap::new();
                    for key in &main_data.air_header {
                        let value = csv_item.get(key).cloned().unwrap_or(Value::Null);

                        // 将数值字段转换为浮点数
                        if key == "交易金额" {
                            let num_value = match value {
                                Value::String(s) => s.parse::<f64>().unwrap_or(0.0),
                                Value::Number(n) => n.as_f64().unwrap_or(0.0),
                                _ => 0.0,
                            };
                            new_obj.insert(
                                key.clone(),
                                Value::Number(
                                    serde_json::Number::from_f64(num_value)
                                        .unwrap_or(serde_json::Number::from(0)),
                                ),
                            );
                        } else {
                            new_obj.insert(key.clone(), value);
                        }
                    }

                    // 设置计数值，初始为1
                    let count = if is_repeat { 2 } else { 1 };
                    new_obj.insert(
                        "计数".to_string(),
                        Value::Number(serde_json::Number::from(count)),
                    );

                    // 如果是月末，添加标记
                    if is_month_end {
                        new_obj.insert("_isMonthEnd".to_string(), Value::Bool(true));
                        // 同时为原始数据项添加标记，与Python版本保持一致
                        let mut item_mut = item.clone();
                        item_mut.insert("_isMonthEnd".to_string(), Value::Bool(true));
                    }

                    is_repeat = true;
                    air_data2.push(new_obj);
                }
            }
        }
    }

    // 计算货币汇总
    let pay_sum = currency_sum(&pay_data, "货币单位", "订单总价");
    let air_sum = currency_sum(&air_data, "货币单位", "订单总价");
    let pay_sum2 = currency_sum(&pay_data2, "币种", "总额");
    let air_sum2 = currency_sum(&air_data2, "交易币种", "交易金额");

    // 合并所有货币类型
    let mut currency_set = std::collections::HashSet::new();
    for currency in pay_sum.keys() {
        currency_set.insert(currency.clone());
    }
    for currency in air_sum.keys() {
        currency_set.insert(currency.clone());
    }
    for currency in pay_sum2.keys() {
        currency_set.insert(currency.clone());
    }
    for currency in air_sum2.keys() {
        currency_set.insert(currency.clone());
    }

    // 创建汇总数据
    let mut total_data = Vec::new();
    for currency in currency_set {
        let mut obj = HashMap::new();
        obj.insert("币种".to_string(), Value::String(currency.clone()));
        obj.insert(
            "店铺筛paypal".to_string(),
            Value::Number(
                serde_json::Number::from_f64(*pay_sum.get(&currency).unwrap_or(&0.0))
                    .unwrap_or(serde_json::Number::from(0)),
            ),
        );
        obj.insert(
            "paypal".to_string(),
            Value::Number(
                serde_json::Number::from_f64(*pay_sum2.get(&currency).unwrap_or(&0.0))
                    .unwrap_or(serde_json::Number::from(0)),
            ),
        );
        obj.insert(
            "店铺筛云汇".to_string(),
            Value::Number(
                serde_json::Number::from_f64(*air_sum.get(&currency).unwrap_or(&0.0))
                    .unwrap_or(serde_json::Number::from(0)),
            ),
        );
        obj.insert(
            "云汇".to_string(),
            Value::Number(
                serde_json::Number::from_f64(*air_sum2.get(&currency).unwrap_or(&0.0))
                    .unwrap_or(serde_json::Number::from(0)),
            ),
        );
        total_data.push(obj);
    }

    // 按币种排序
    total_data.sort_by(|a, b| {
        let a_currency = a.get("币种").and_then(|v| v.as_str()).unwrap_or("");
        let b_currency = b.get("币种").and_then(|v: &Value| v.as_str()).unwrap_or("");
        a_currency.cmp(b_currency)
    });

    // 创建Excel工作簿并导出数据
    let mut workbook = Workbook::new();

    // 创建工作表：原始数据
    let mut sheet1 = workbook.add_worksheet().set_name("原始数据")?;
    export_sheet_data(&mut sheet1, &new_data, true)?;

    // 创建工作表：店铺筛Paypal
    let mut sheet2 = workbook.add_worksheet().set_name("店铺筛Paypal")?;
    export_sheet_data(&mut sheet2, &pay_data, true)?;

    // 创建工作表：csv-PayPal
    let mut sheet3 = workbook.add_worksheet().set_name("csv-PayPal")?;
    export_sheet_data(&mut sheet3, &pay_data2, true)?;

    // 创建工作表：店铺筛云汇
    let mut sheet4 = workbook.add_worksheet().set_name("店铺筛云汇")?;
    export_sheet_data(&mut sheet4, &air_data, true)?;

    // 创建工作表：csv-云汇订单
    let mut sheet5 = workbook.add_worksheet().set_name("csv-云汇订单")?;
    export_sheet_data(&mut sheet5, &air_data2, true)?;

    // 创建工作表：汇总
    let mut sheet6 = workbook.add_worksheet().set_name("汇总")?;

    // 为汇总表格指定特定的列顺序
    let summary_columns = vec![
        "币种".to_string(),
        "店铺筛paypal".to_string(),
        "paypal".to_string(),
        "店铺筛云汇".to_string(),
        "云汇".to_string(),
    ];
    export_sheet_data_with_columns(&mut sheet6, &total_data, &summary_columns, true)?;

    // 获取导出文件名
    let e_file_name = get_export_filename(excel_files, export_file_name);
    let output_file = create_filename(&e_file_name);

    // 保存Excel文件
    workbook.save(&output_file)?;
    info!("Excel 文件导出成功！{}", output_file);

    Ok(output_file)
}

/// 导出数据到Excel工作表（使用指定列顺序）
fn export_sheet_data_with_columns(
    worksheet: &mut Worksheet,
    data: &[HashMap<String, Value>],
    columns: &[String],
    auto_filter: bool,
) -> Result<()> {
    if data.is_empty() {
        return Ok(());
    }

    // 创建黄色背景格式
    let yellow_format = Format::new().set_background_color(Color::RGB(0xFFFF00));

    // 写入表头
    for (col_idx, column) in columns.iter().enumerate() {
        worksheet.write_string(0, col_idx as u16, column)?;
    }

    // 写入数据
    for (row_idx, item) in data.iter().enumerate() {
        let is_month_end = item
            .get("_isMonthEnd")
            .and_then(|v| v.as_bool())
            .unwrap_or(false);

        for (col_idx, column) in columns.iter().enumerate() {
            if let Some(value) = item.get(column) {
                let row = (row_idx + 1) as u32;
                let col = col_idx as u16;

                match value {
                    Value::String(s) => {
                        if is_month_end {
                            worksheet.write_string_with_format(row, col, s, &yellow_format)?;
                        } else {
                            worksheet.write_string(row, col, s)?;
                        }
                    }
                    Value::Number(n) => {
                        if let Some(f) = n.as_f64() {
                            if is_month_end {
                                worksheet.write_number_with_format(row, col, f, &yellow_format)?;
                            } else {
                                worksheet.write_number(row, col, f)?;
                            }
                        } else if let Some(i) = n.as_i64() {
                            if is_month_end {
                                worksheet.write_number_with_format(
                                    row,
                                    col,
                                    i as f64,
                                    &yellow_format,
                                )?;
                            } else {
                                worksheet.write_number(row, col, i as f64)?;
                            }
                        }
                    }
                    Value::Bool(b) => {
                        if is_month_end {
                            worksheet.write_boolean_with_format(row, col, *b, &yellow_format)?;
                        } else {
                            worksheet.write_boolean(row, col, *b)?;
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    // 设置自动筛选
    if auto_filter && !data.is_empty() {
        worksheet.autofilter(0, 0, data.len() as u32, columns.len() as u16 - 1)?;
    }

    Ok(())
}

/// 导出数据到Excel工作表
fn export_sheet_data(
    worksheet: &mut Worksheet,
    data: &[HashMap<String, Value>],
    auto_filter: bool,
) -> Result<()> {
    if data.is_empty() {
        return Ok(());
    }

    // 收集所有可能的列名
    let mut all_columns = std::collections::HashSet::new();
    for item in data {
        for key in item.keys() {
            if key != "_isMonthEnd" {
                // 排除内部标记字段
                all_columns.insert(key.clone());
            }
        }
    }

    // 转换为有序列表
    let mut columns: Vec<String> = all_columns.into_iter().collect();
    columns.sort(); // 按字母顺序排序列名

    // 优先处理特定列
    let priority_columns = vec![
        "支付订单号",
        "交易号",
        "交易编号",
        "币种",
        "交易币种",
        "货币单位",
        "订单总价",
        "总额",
        "交易金额",
    ];
    for &col in priority_columns.iter().rev() {
        if let Some(pos) = columns.iter().position(|x| x == col) {
            columns.remove(pos);
            columns.insert(0, col.to_string());
        }
    }

    // 创建黄色背景格式
    let yellow_format = Format::new().set_background_color(Color::RGB(0xFFFF00));

    // 写入表头
    for (col_idx, column) in columns.iter().enumerate() {
        worksheet.write_string(0, col_idx as u16, column)?;
    }

    // 写入数据
    for (row_idx, item) in data.iter().enumerate() {
        let is_month_end = item
            .get("_isMonthEnd")
            .and_then(|v| v.as_bool())
            .unwrap_or(false);

        for (col_idx, column) in columns.iter().enumerate() {
            if let Some(value) = item.get(column) {
                let row = (row_idx + 1) as u32;
                let col = col_idx as u16;

                match value {
                    Value::String(s) => {
                        if is_month_end {
                            worksheet.write_string_with_format(row, col, s, &yellow_format)?;
                        } else {
                            worksheet.write_string(row, col, s)?;
                        }
                    }
                    Value::Number(n) => {
                        if let Some(f) = n.as_f64() {
                            if is_month_end {
                                worksheet.write_number_with_format(row, col, f, &yellow_format)?;
                            } else {
                                worksheet.write_number(row, col, f)?;
                            }
                        } else if let Some(i) = n.as_i64() {
                            if is_month_end {
                                worksheet.write_number_with_format(
                                    row,
                                    col,
                                    i as f64,
                                    &yellow_format,
                                )?;
                            } else {
                                worksheet.write_number(row, col, i as f64)?;
                            }
                        }
                    }
                    Value::Bool(b) => {
                        if is_month_end {
                            worksheet.write_boolean_with_format(row, col, *b, &yellow_format)?;
                        } else {
                            worksheet.write_boolean(row, col, *b)?;
                        }
                    }
                    _ => {}
                }
            }
        }
    }

    // 设置自动筛选
    if auto_filter && !data.is_empty() {
        let last_col = columns.len() as u16 - 1;
        let last_row = data.len() as u32;
        worksheet.autofilter(0, 0, last_row, last_col)?;
    }

    // 设置列宽
    for (col_idx, _) in columns.iter().enumerate() {
        worksheet.set_column_width(col_idx as u16, 15.0)?; // 默认列宽
    }

    // 特定列的宽度调整
    if let Some(pos) = columns
        .iter()
        .position(|x| x == "支付订单号" || x == "交易号" || x == "交易编号")
    {
        worksheet.set_column_width(pos as u16, 20.0)?;
    }

    Ok(())
}

/// 交互式命令行界面
fn interactive_mode() -> Result<()> {
    SimpleLogger::new()
        .with_level(log::LevelFilter::Info)
        .init()
        .unwrap_or(());

    let config = load_config("config.json")?;

    loop {
        println!("小娇娇Excel数据处理工具 (Rust版)");
        println!(
            "{}",
            [
                iter::repeat("*").take(30).collect::<String>(),
                "注意事项".to_string(),
                iter::repeat("*").take(30).collect::<String>()
            ]
            .join("")
        );
        println!("1.文件命名最好要规范");
        println!("2.csv文件需要把头部无关信息删除");
        println!("3.csv文件支持转成xlsx文件读取");
        println!("4.文件夹路径 在文件管理最上方输入框获取");
        println!("5.命令行中 ↑ ↓ 箭头切换粘贴信息,鼠标右键直接粘贴选项");
        println!("6.直接按 Enter 键结束");
        println!("7.可以修改config.json配置文件自定义参数");
        println!("{}", iter::repeat("*").take(70).collect::<String>());

        // 检查配置文件中是否有预设的文件路径
        let mut excel_files = config.file_paths.excel_files.clone();
        let mut pay_csv_files = config.file_paths.paypal_csv_files.clone();
        let mut air_csv_files = config.file_paths.air_csv_files.clone();
        let mut export_file_name = config.output.export_file_name.clone();

        let mut use_config = false;

        // 检查配置文件中是否有预设的文件路径
        if !excel_files.is_empty() && (!pay_csv_files.is_empty() || !air_csv_files.is_empty()) {
            println!("\n检测到配置文件中有预设的文件路径:");
            println!("Excel文件: {}", excel_files.join(", "));
            println!("PayPal CSV文件: {}", pay_csv_files.join(", "));
            println!("云汇 CSV文件: {}", air_csv_files.join(", "));

            println!("是否使用配置文件中的设置？(Y/N): ");
            let mut input = String::new();
            io::stdin().read_line(&mut input)?;
            if input.trim().to_lowercase() == "y" {
                use_config = true;
            }
        }

        if !use_config {
            println!("\n请输入以下信息：");

            // 获取Excel文件路径
            excel_files.clear();
            loop {
                println!("Excel店铺文件路径 (输入空行结束): ");
                let mut input = String::new();
                io::stdin().read_line(&mut input)?;
                let input = input.trim();

                if input.is_empty() {
                    break;
                }

                if Path::new(input).exists() {
                    excel_files.push(input.to_string());
                } else {
                    println!("文件不存在: {}", input);
                }
            }

            if excel_files.is_empty() {
                println!("错误：至少需要一个Excel文件");
                continue;
            }

            // 获取PayPal CSV文件路径
            pay_csv_files.clear();
            loop {
                println!("PayPal CSV文件路径(输入空行结束): ");
                let mut input = String::new();
                io::stdin().read_line(&mut input)?;
                let input = input.trim();

                if input.is_empty() {
                    break;
                }

                if Path::new(input).exists() {
                    pay_csv_files.push(input.to_string());
                } else {
                    println!("文件不存在: {}", input);
                }
            }

            // 获取云汇CSV文件路径
            air_csv_files.clear();
            loop {
                println!("云汇 CSV文件路径(输入空行结束): ");
                let mut input = String::new();
                io::stdin().read_line(&mut input)?;
                let input = input.trim();

                if input.is_empty() {
                    break;
                }

                if Path::new(input).exists() {
                    air_csv_files.push(input.to_string());
                } else {
                    println!("文件不存在: {}", input);
                }
            }

            // 获取输出文件名
            if !config.output.auto_name {
                println!("输出Excel文件名,需要后缀.xlsx (选填): ");
                let mut input = String::new();
                io::stdin().read_line(&mut input)?;
                export_file_name = input.trim().to_string();
            }
        }

        // 执行主函数
        match process_files(
            &excel_files,
            &pay_csv_files,
            &air_csv_files,
            if export_file_name.is_empty() {
                None
            } else {
                Some(export_file_name.clone())
            },
            &config,
        ) {
            Ok(output_file) => {
                println!("处理完成，输出文件: {}", output_file);
            }
            Err(e) => {
                error!("处理失败: {}", e);
                println!("处理失败: {}", e);
            }
        }

        // 询问是否继续处理下一批文件
        println!("\n是否继续处理下一批文件？(Y/N): ");
        let mut input = String::new();
        io::stdin().read_line(&mut input)?;
        if input.trim().to_lowercase() != "y" {
            println!("程序退出，感谢使用！");
            break;
        }
    }

    Ok(())
}

fn main() -> Result<()> {
    // 初始化日志
    SimpleLogger::new()
        .with_level(log::LevelFilter::Info)
        .init()
        .unwrap_or(());

    // 解析命令行参数
    let args = Args::parse();

    if args.interactive || (args.excel.is_none() && args.paypal.is_none() && args.air.is_none()) {
        // 交互模式
        interactive_mode()
    } else {
        // 加载配置文件
        let config = load_config("config.json")?;
        // 命令行模式
        let excel_files = args.excel.unwrap_or_default();
        let paypal_files = args.paypal.unwrap_or_default();
        let air_files = args.air.unwrap_or_default();

        if excel_files.is_empty() {
            return Err(anyhow!("错误：至少需要一个Excel文件"));
        }

        process_files(
            &excel_files,
            &paypal_files,
            &air_files,
            args.output,
            &config,
        )?;
        Ok(())
    }
}
